package com.hexinfo.dmpro.monitor.service;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.hexinfo.dmpro.monitor.config.MonitorCache;
import com.hexinfo.dmpro.monitor.dao.ImpalaAppDao;
import com.hexinfo.dmpro.monitor.model.ImpalaAppModel;
import com.hexinfo.dmpro.monitor.model.YarnAppModel;
import com.hexinfo.dmpro.monitor.model.base.MonitorBaseModel;
import com.hexinfo.dmpro.monitor.model.base.MonitorReq;
import com.hexinfo.dmpro.monitor.model.cm.DetailResourceInfo;
import com.hexinfo.dmpro.monitor.model.serviceparam.CmTargetServiceModel;
import com.hexinfo.dmpro.monitor.service.serviceparam.CmTargetParamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author peng
 * @date 2021/9/28 14:17
 */
@Service
@Slf4j
public class ImpalaService {

    private int SUCESS_CODE = 200;

    @Autowired
    private CmImpalaAppService cmImpalaAppService;

    @Autowired
    private ImpalaAppDao impalaAppDao;
    @Autowired
    private CmTargetParamService cmTargetParamService;
    @Autowired
    private CmImpalaService cmImpalaService;
    @Autowired
    private ClusterWhService clusterWhService;

    @Value("${warn.cmImpalaResourceWarn}")
    private String cmImpalaResourceWarn;
    @Value("${warn.cmImpalaMemoryUse}")
    private String cmImpalaMemoryUse;
    @Value("${warn.cmImpalaRunTime}")
    private String cmImpalaRunTime;
    @Value("${warn.cmImpalaRunNumber}")
    private String cmImpalaRunNumber;

    /**
     * @param req
     * @param flag
     * @return
     */
    public List<ImpalaAppModel> getCmApiImpalaApp(MonitorReq req, boolean flag) {

        String serviceName = MonitorCache.getServiceName(req.getCenterId(), req.getCmFlag(), req.getClusterFlag(), "impala");
        //集群没有impala服务时，直接退出
        if (StrUtil.isBlank(serviceName)){
            return new ArrayList<ImpalaAppModel>();
        }
        req.setServiceName(serviceName);
        List<ImpalaAppModel> impalaApps = cmImpalaAppService.getImpalaApps(req);
        if (flag) {
            if (impalaApps != null && impalaApps.size() > 0) {
                try {
                    //impala任务资源使用情况监控
                    impalaWarn(impalaApps,req);
                }catch (Exception e){
                    log.error("impala任务资源使用情况监控异常");
                    e.printStackTrace();
                }
                for (ImpalaAppModel impalaApp : impalaApps) {
                    try {
                        impalaApp.setCenterId(req.getCenterId());
                        impalaApp.setCenterName(req.getCenterName());
                        impalaApp.setCmFlag(req.getCmFlag());
                        impalaApp.setCmName(req.getCmName());
                        impalaApp.setClusterFlag(req.getClusterFlag());
                        impalaApp.setClusterName(req.getClusterName());
                        impalaApp.setTaskTime(req.getTaskTime());
//                        impalaAppDao.updateInsertApp(impalaApp);
                        impalaAppDao.delInsertApp(impalaApp);
                        impalaAppDao.upInsertApp(impalaApp);
                    }catch (Exception e){
                        log.error("任务监控impala任务插入数据库报错："+e);
                    }
                }
            }
        }
        return impalaApps;
    }

    /**
     * impala任务资源使用情况监控
     */
    public String impalaWarn(List<ImpalaAppModel> impalaApps, MonitorReq req) {
        StringBuffer warnAlert = new StringBuffer();
        //impala任务预警配置信息
//        CmTargetServiceModel memoryModel = cmTargetParamService.queryTargetCode(cmImpalaMemoryUse);
        CmTargetServiceModel timeModel = cmTargetParamService.queryTargetCode(cmImpalaRunTime);
        CmTargetServiceModel numberModel = cmTargetParamService.queryTargetCode(cmImpalaRunNumber);
//        //获取集群资源池信息
//        List<DetailResourceInfo> DetailResourceInfos = cmImpalaService.queryRootPool(req.getCmFlag(), req.getClusterFlag());
//        //集群信息
//        MonitorBaseModel monitorBaseModel = clusterWhService.queryCmInfo(req.getCmFlag(), req.getClusterFlag());
//        //按照资源池转化为Map
//        Map<String, DetailResourceInfo> map = DetailResourceInfos.stream()
//                .collect(Collectors.toMap(DetailResourceInfo::getPoolName, Function.identity()));
        int runNum = 0;
        for (ImpalaAppModel impalaApp : impalaApps) {
            String warnLog = "";
            //（1）impala任务持续时间超过N小时
            if (timeModel != null){
                long num = Long.parseLong(impalaApp.getDuration());
                long l = Long.parseLong(timeModel.getDefaultValue())*1000*60;
                if (num > l){
                    double result = (double) num / (1000*60);
                    DecimalFormat decimalFormat = new DecimalFormat("#");
                    warnLog += "持续时间："+decimalFormat.format(result)+"分钟，告警值："+timeModel.getDefaultValue()+"分钟"+"\n";
                }
            }
            //（2）impala任务正在执行的任务数超过N个
            if ("RUNNING".equalsIgnoreCase(impalaApp.getState())){
                runNum++;
            }
            if (StrUtil.isNotBlank(warnLog)){
                //sql截取
                String sql = "";
                if (impalaApp.getImpalaSql().length() <= 100) {
                    sql = impalaApp.getImpalaSql();
                } else {
                    sql = impalaApp.getImpalaSql().substring(0, 100) + "...";
                }
                warnLog = "任务名："+sql+"\n"+
                        "任务id："+impalaApp.getAppId()+"\n"+
                        "任务类型："+impalaApp.getQueryType()+"\n"+
                        "池："+impalaApp.getResourcePool()+"\n"+
                        warnLog+"\n";
                warnAlert.append(warnLog);
            }
        }
        if (numberModel != null){
            int warnNum = Integer.parseInt(numberModel.getDefaultValue());
            if(runNum > warnNum){
                warnAlert.insert(0,"impala进行中的任务数："+runNum+"，告警值："+warnNum+"\n");
            }
        }
        if(StrUtil.isNotEmpty(warnAlert)){
            warnAlert.insert(0,"【impala任务资源告警】"+"\n"+"【"+req.getCmName()+"--"+req.getClusterName()+"】"+"\n");
            //发送yarn任务告警，钉钉
            cmTargetParamService.warnWxDingDingAndLog(req.getCmFlag(),req.getCmName(),req.getClusterFlag(),
                    req.getClusterName(),"impala",warnAlert.toString(),cmImpalaResourceWarn);
        }
        return warnAlert.toString();
    }
}
